#include "Tank.h"
#include "../Game.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_AudioManager.h"

#define MAX_COOLDOWN 130.0f
#define MAX_COOLDOWN_REMAIN 10.0f
//#define LVL1_HEIGHT 
//#define LVL1_WIDTH 
//#define LVL1_HEIGHT
//#define LVL1_WIDTH 
//#define LVL1_HEIGHT 
//#define LVL1_WIDTH 
CTank::CTank()
{
	m_fEndurance = 20.0f;
	m_fStrength = 13;
	m_fSpeed = 40;
	m_fDexterity = 11;
	m_fSprint = 65;
	m_fDash = 230;
	m_fMaxStamina = 100;
	m_fCurrStamina = 100;
	m_fRegenRate = 10;
	m_fDash = 150;
	m_fCooldown = MAX_COOLDOWN;
	m_fAbilityDelay = MAX_COOLDOWN_REMAIN;
	m_bOnCD = false;

	m_fSurgeTimer = 0;
}


CTank::~CTank()
{
}

void CTank::Update(float elapsedTime)
{
	if (m_fSurgeTimer > 0.0f)
		m_fSurgeTimer -= elapsedTime;
	if (m_fSurgeTimer <= 0.0f)
	{
		//set tank stats back to normal from surge.
		m_nKnockBack = 7;
		m_fSurgeTimer = 8.0f;


		m_fEndurance = 20.0f;
		m_fStrength = 13;
		m_fSpeed = 40;
		m_fDexterity = 11;
		m_fSprint = 65;

		m_fRegenRate = 10;

		SetSize(m_szSize);
	}

	//Cooldown
	if (MAX_COOLDOWN > GetCooldown())
	{
		//cooldown bar for using abilities.
		SetCooldown(GetCooldown() + 10 * elapsedTime);
		//Have we used any abilities?
		if (GetCDFlag())
		{
			//Has the delay for ability usage expired?
			if ((GetAbilityDelay() <= 0.0f))
			{
				//Allow us to use abilites again.
				SetAbilityDelay(10);
				SetCDFlag(false);
			}
			else
			{
				//Decrement ability Delay timer.
				SetAbilityDelay(GetAbilityDelay() - elapsedTime);
			}
		}
	}

	if (m_fCurrStamina < 1)
	{
		m_bExhausted = true;
		if (m_bCarrying == true)
		{
			m_bCarrying = false;
		}
	}

	if (m_fCurrStamina > 60)
	{
		m_bExhausted = false;
	}

	if (SGD::InputManager::GetInstance()->IsControllerConnected(m_iconnum))
		Input();
	CPlayer::Update(elapsedTime);
}

void CTank::Input()
{
	SGD::InputManager* pInput = SGD::InputManager::GetInstance();
	SGD::Vector c = pInput->GetLeftJoystick(GetControllernumber());

	bool sprinting = false;

	if (pInput->IsButtonDown(GetControllernumber(), 5))
	{
		if (m_bExhausted == false && m_bCarrying == false)
		{
			m_fCurrStamina -= 0.01f;
			sprinting = true;
		}
	}
	else
	{
		if (m_fCurrStamina < m_fMaxStamina)
			m_fCurrStamina += 0.01f;
	}

	if (pInput->IsButtonPressed(0, 0))
	{
		m_ptPosition.x += 10;
	}
	if (pInput->IsKeyDown(SGD::Key::W))
	{
		m_vtVelocity = { 0, -64 };
	}
	else if (pInput->IsKeyDown(SGD::Key::S))
	{
		m_vtVelocity = { 0, 64 };
	}
	else if (pInput->IsKeyDown(SGD::Key::A))
	{
		m_vtVelocity = { -64, 0 };
	}
	else if (pInput->IsKeyDown(SGD::Key::D))
	{
		m_vtVelocity = { 64, 0 };
	}

	if (c.y == 0 && c.x <= 0.5 && c.x >= 0 &&
		pInput->IsKeyDown(SGD::Key::W) == false
		&& pInput->IsKeyDown(SGD::Key::A) == false
		&& pInput->IsKeyDown(SGD::Key::S) == false
		&& pInput->IsKeyDown(SGD::Key::D) == false)
	{
		if (m_bPlayerStun == false)
		m_vtVelocity = { 0, 0 };
		if (this->currAnimation.GetName() != "tankIdleB" && m_bTeam == false)
			CAnimationManager::GetInstance()->SetOwner(this, "tankIdleB");
		else if (this->currAnimation.GetName() != "tankIdleR" && m_bTeam == true)
			CAnimationManager::GetInstance()->SetOwner(this, "tankIdleR");
	}
	else
	{
		if (this->currAnimation.GetName() != "tankWalkB" && m_bTeam == false)
			CAnimationManager::GetInstance()->SetOwner(this, "tankWalkB");
		else if (this->currAnimation.GetName() != "tankWalkR" && m_bTeam == true)
			CAnimationManager::GetInstance()->SetOwner(this, "tankWalkR");
	}



	if (m_bSprinting && m_bDash == false)
		CPlayer::Input(m_fSprint);
	else if (m_bSprinting == false && m_bDash == true)
	{
		CPlayer::Input(m_fDash);
	}
	else
	{
		if (m_bExhausted == true)
			m_fSpeed = 12;
		else
			m_fSpeed = 24;

		CPlayer::Input(m_fSpeed);
	}

	if (!GetCDFlag())
	{

		if (m_nButton == 2)
		{
			// they used the X Ability DO STUFF
			// Reset the button so it doesn't do the ability again
			m_nButton = 0;
			if (m_fCharging <= 30 && GetCharge() >= 10)
			{
				//use the first level
				SetCDFlag(true);
				SetCooldown(0);
				Surge(1);

				// take away from the ability meter by 10 the lowest charge
				//if they just tap the ability button they can use a level 1 if they have it
				m_fAbilityCharge -= 10;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
			else if (m_fCharging > 30 && m_fCharging < 60 && GetCharge() >= 59)
			{
				//use level 2
				SetCDFlag(true);
				SetCooldown(0);

				Surge(2);

				// take away from the ability meter by which level they used
				m_fAbilityCharge -= 30;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
			else if (m_fCharging >= 59)
			{
				//use level 3
				SetCDFlag(true);
				SetCooldown(0);

				Surge(3);

				// take away from the ability meter by which level they used
				m_fAbilityCharge -= 60;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
		}

	}


	if (!GetCDFlag())
	{

		if (m_nButton == 3)
		{
			// they used the Y Ability DO STUFF
			// Reset the button so it doesn't do the ability again
			m_nButton = 0;
			if (m_fCharging <= 30 && GetCharge() >= 10)
			{
				//use the first level
				SetCDFlag(true);
				SetCooldown(0);

				Smash(1);

				// take away from the ability meter by 10 the lowest charge
				//if they just tap the ability button they can use a level 1 if they have it
				m_fAbilityCharge -= 10;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
			else if (m_fCharging > 30 && m_fCharging < 60 && GetCharge() > 30)
			{
				//use level 2
				SetCDFlag(true);
				SetCooldown(0);

				Smash(2);

				// take away from the ability meter by which level they used
				m_fAbilityCharge -= 30;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
			else if (m_fCharging >= 59)
			{
				//use level 3
				SetCDFlag(true);
				SetCooldown(0);

				Smash(3);

				// take away from the ability meter by which level they used
				m_fAbilityCharge -= 60;

				//reset the charging meter to 0
				m_fCharging = 0;
			}
		}
	}
}

void	CTank::Render(void)
{
	if (m_bCarrying == true)
	{
		//ball carrying indicator
		SGD::GraphicsManager::GetInstance()->DrawRectangle({ SGD::Point{ (m_ptPosition.x - Game::GetInstance()->GetCameraPos().x - 20), (m_ptPosition.y - Game::GetInstance()->GetCameraPos().y - 30) },
			m_szSize * 2 }, SGD::Color{ 255, 175, 0 }, { 0, 0, 0 }, 3);
	}

	//SGD::GraphicsManager::GetInstance()->DrawRectangle({ SGD::Point{ (m_ptPosition.x - Game::GetInstance()->GetCameraPos().x), (m_ptPosition.y - Game::GetInstance()->GetCameraPos().y) }, m_szSize },
	//	SGD::Color{ 0, 0, 255 }, { 0, 0, 0 }, 3);

	SGD::GraphicsManager::GetInstance()->DrawTexture(Game::GetInstance()->GetArrow(), { m_ptPosition.x, m_ptPosition.y + m_szSize.height / 2 }, m_fRotation, { 112, 112 }, {}, { 0.4f, 0.4f });

	//Ability meter stuff
	CPlayer::Render();

	//Cooldown bar
	SGD::Rectangle temp = this->GetAbilityRect();
	temp.top = temp.bottom - 10;
	temp.right = GetCooldown();
	if (GetCooldown() < MAX_COOLDOWN)
	{
		SGD::GraphicsManager::GetInstance()->DrawRectangle(temp, { 255, 255, 255 });
		float dProgress = ((float)GetCooldown() / MAX_COOLDOWN)*100.0f;
		SGD::OStringStream buffer;
		buffer << "Ability CD:" << (int)dProgress << "%";
		SGD::GraphicsManager::GetInstance()->DrawString(buffer.str().c_str(), { temp.left, temp.bottom });
	}


	//Ability Icons
	temp.top = temp.bottom + 20;
	temp.bottom = temp.top + 50;
	temp.right = temp.left + 50;
	SGD::OStringStream buffer;
	float dProgress = ((float)GetCooldown() / MAX_COOLDOWN)*100.0f;

	buffer << GetAbilityDelay();
	SGD::GraphicsManager::GetInstance()->DrawRectangle(temp, { 155, 155, 155 });
	SGD::GraphicsManager::GetInstance()->DrawString(buffer.str().c_str(), { temp.left + 23, temp.top + 23 });

	//Radial effect on cooldown
	SGD::GraphicsManager::GetInstance()->DrawLine({ temp.left + 23, temp.top + 23 }, { temp.left + 23, temp.top }, SGD::Color(0, 255, 0));
	SGD::Point tempPoint = SGD::Point{ temp.left + 23, temp.top };

	temp.left = temp.right + 10;
	temp.right = temp.left + 50;

	SGD::GraphicsManager::GetInstance()->DrawRectangle(temp, { 155, 155, 155 });
	SGD::GraphicsManager::GetInstance()->DrawString(buffer.str().c_str(), { temp.left + 23, temp.top + 23 });

	SGD::GraphicsManager::GetInstance()->DrawLine({ temp.left + 23, temp.top + 23 }, { temp.left + 23, temp.top }, SGD::Color(0, 255, 0));
	tempPoint = SGD::Point{ temp.left + 23, temp.top };
}


void CTank::Surge(int prmLevel)
{
	switch (prmLevel)
	{
	case 1:
	{

			  //Stat buffs
			  m_nKnockBack = 30;
			  m_fSurgeTimer = 8.0f;


			  m_fEndurance = 25.0f;
			  m_fStrength = 25.0f;
			  m_fSpeed = 28;
			  m_fDexterity = 13;
			  m_fSprint = 70;

			  m_fRegenRate = 13;
			  //increase size;
			  //TODO: use pound defines.
			  originalSize = m_szSize;
			  m_szSize = { m_szSize.width + 20, m_szSize.height + 20 };

			  originalSize = m_szSize;
			  m_szSize = { m_szSize.width + 20, m_szSize.height + 20 };

	}
		break;
	case 2:
	{
			  //Stat buffs

			  m_nKnockBack = 50;
			  m_fSurgeTimer = 10.0f;

			  m_fEndurance = 30.0f;
			  m_fStrength = 30.0f;
			  m_fSpeed = 32;
			  m_fDexterity = 16;
			  m_fSprint = 75;

			  m_fRegenRate = 16;

			  //increase size;
			  //TODO: use pound defines.

			  originalSize = m_szSize;
			  m_szSize = { m_szSize.width + 35, m_szSize.height + 35 };


	}
		break;
	case 3:
	{
			  //Stat buffs
			  m_nKnockBack = 100;
			  m_fSurgeTimer = 12.0f;

			  m_fEndurance = 33.0f;
			  m_fStrength = 33.0f;
			  m_fSpeed = 36;


			  m_fDexterity = 20;
			  m_fSprint = 80;


			  m_fRegenRate = 20;

			  //increase size;
			  //TODO: use pound defines.
			  originalSize = m_szSize;
			  m_szSize = { m_szSize.width + 50, m_szSize.height + 50 };
	}
		break;
	default:
		break;
	}

}

void CTank::Smash(int prmLevel)
{
	m_nAbilityLevel = prmLevel;
	SGD::Event* pEvent = new SGD::Event("SMASH!", &m_nAbilityLevel, this);

	pEvent->QueueEvent();
}